<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title></title>
	</head>
	<body>
	</body>
	<script type="text/javascript">
//一.如何从外部读取局部变量n？执行f1(),弹出999
 /*    function f1() {
		var n = 999;
	   function f2() {
			alert(n);
		}
	}
	f1(); //什么也不执行
 // f1()();//报错f1(...) is not a function  */

// 解决办法
 //1.自执行函数(立即执行函数) (function(){})()
/* function f1(){
　　var n=999;
　　(function f2(i){ 
　　　　alert(i); 
　　})(n)
}
f1(); //999 */

//2.闭包 
  function f1(){
　　var n=999;
　　function f2(){  
　　　　alert(n); 
　　}
　　return f2;  //这个就是闭包,闭包就是将函数内部和函数外部连接起来的一座桥梁
}
f1()(); //999 

//二.看下面代码，给出输出结果。
/*  for(var i=1;i<=3;i++){ //同步执行
    
	setTimeout(function(){ //异步执行
      console.log(i);   //4,4,4
    },0); 
 
} */

//如何让上述代码输出1 2 3？

// 1. 自执行函数法=(function(){})()
/* for(var i=1;i<=3;i++){ 
	 (function(a){
		 setTimeout(function(){   //自执行函数法
		     console.log(a);   
		    },0)
	 })(i)
} */


//2. 声明变量用let 块级作用域
// let相当于var
// var 作用域：全局，函数
// let 作用域：全局，函数，块级

/* for(let i=1;i<=3;i++){ 
  setTimeout(function(){
      console.log(i);   //1,2,3
  },0) 
} */


// 三.相关面试题
   /*    for (var i = 0; i <= 5; i++) {  //同步，i变成6
            ((a) => {
                setTimeout(() => {  //异步
                    console.log(a);
                }, a * 1000)
            })(i)
        }
        console.log(i); //同步  //6,0,1,2,3,4,5后面从0开始是间隔1秒执行  */

	// 	闭包总结：
	// 闭包说的通俗⼀点就是打通了⼀条在函数外部访问函数内部作⽤域的通道。正常情况下函数外部是访问不到函数内部作⽤域变量的，
	// 如何判断是不是闭包: 函数嵌套函数, 内部函数被return，内部函数调⽤外层函数的局部变量
	// 优点：可以隔离作⽤域，不造成全局污染
	// 缺点：由于闭包⻓期驻留内存，则⻓期这样会导致内存泄露
	// 如何解决内存泄露：将暴露在外部的闭包变量置为null



	</script>
</html>
